package com.gutetec.cms.bmc;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;

import javax.servlet.DispatcherType;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.gutetec.cms.bmc.db.dbUtil.FmDBUtil;
import com.gutetec.cms.bmc.db.dbUtil.FmDbMapper;
import com.gutetec.cms.bmc.resource.AlarmResource;
import com.gutetec.cms.bmc.resource.ChannleResource;
import com.gutetec.cms.bmc.resource.CiTaskResource;
import com.gutetec.cms.bmc.resource.ConfigResource;
import com.gutetec.cms.bmc.resource.FileDistributeResource;
import com.gutetec.cms.bmc.resource.FileInfoResource;
import com.gutetec.cms.bmc.resource.MonitorResource;
import com.gutetec.cms.bmc.resource.NodeResource;
import com.gutetec.cms.bmc.resource.SubNodeResource;
import com.gutetec.cms.bmc.resource.TaskDisResource;

import io.dropwizard.Application;
import io.dropwizard.assets.AssetsBundle;
import io.dropwizard.db.DataSourceFactory;
import io.dropwizard.hibernate.HibernateBundle;
import io.dropwizard.migrations.MigrationsBundle;
import io.dropwizard.server.SimpleServerFactory;
import io.dropwizard.setup.Bootstrap;
import io.dropwizard.setup.Environment;
import io.swagger.jaxrs.config.BeanConfig;
import io.swagger.jaxrs.listing.ApiListingResource;

/***
 * 微服务主程序
 * @author macui
 *
 */
public class BmcApp extends Application<BmcConfiguration> {
	
	 HibernateBundle<BmcConfiguration> hibernateBundle;
	 
	 /***
	  * main 方法
	  * @param args
	  * @throws Exception
	  */
	 public static void main(String[] args) throws Exception {
	        new BmcApp().run(args);
	    }
	 
	 /***
	  * 初始化
	  */
	 @Override
	public void initialize(Bootstrap<BmcConfiguration> bootstrap) {
		bootstrap.addBundle(new AssetsBundle("/api-doc", "/api-doc", "index.html", "api-doc"));
		
		bootstrap.addBundle(new MigrationsBundle<BmcConfiguration>()
        {
            @Override
            public DataSourceFactory getDataSourceFactory(BmcConfiguration configuration)
            {
                return configuration.getDataSourceFactory();
            }
        });
		
		List<Class<?>> sfEntitysList = initSfEntityClass();
        hibernateBundle = new HibernateBundle<BmcConfiguration>(BmcApp.class,
            sfEntitysList.toArray(new Class<?>[sfEntitysList.size()]))
        {
            @Override
            public DataSourceFactory getDataSourceFactory(BmcConfiguration configuration)
            {
                return configuration.getDataSourceFactory();
            }
        };
        
        bootstrap.addBundle(hibernateBundle);
	}
	 
	@Override
	public void run(BmcConfiguration arg0, Environment environment) throws Exception {
		//Cross domain
        environment.getApplicationContext().addFilter(
            org.eclipse.jetty.servlets.CrossOriginFilter.class, "/api/v1/*",
            EnumSet.of(DispatcherType.REQUEST, DispatcherType.ERROR));
        
        // register resource
        environment.jersey().register(new AlarmResource());
        environment.jersey().register(new ChannleResource());
        environment.jersey().register(new CiTaskResource());
        environment.jersey().register(new ConfigResource());
        environment.jersey().register(new FileDistributeResource());
        environment.jersey().register(new FileInfoResource());
        environment.jersey().register(new MonitorResource());
        environment.jersey().register(new NodeResource());
        environment.jersey().register(new SubNodeResource());
        environment.jersey().register(new TaskDisResource());
        
         // set hibernate session
        FmDBUtil.setSessionFactory(hibernateBundle.getSessionFactory());
        environment.getObjectMapper().setSerializationInclusion(JsonInclude.Include.NON_NULL);
        
        initSwaggerConfig(environment,arg0);
	}
	
	@Override
    public String getName()
    {
        return " BMC APP ";
    }
	
	 private void initSwaggerConfig(Environment environment,BmcConfiguration configuration) {
	        environment.jersey().register(new ApiListingResource());      
	        environment.getObjectMapper().setSerializationInclusion(JsonInclude.Include.NON_NULL);

	        BeanConfig config = new BeanConfig();
	        config.setTitle("GUTETEC Console Service rest API");
	        config.setVersion("1.0.0");
	        config.setResourcePackage("com.gutetec.cms.bmc.resource");
	        
	        SimpleServerFactory simpleServerFactory = (SimpleServerFactory) configuration.getServerFactory();
	        String basePath = simpleServerFactory.getApplicationContextPath();
	        String rootPath = simpleServerFactory.getJerseyRootPath();
	        rootPath = rootPath.substring(0, rootPath.indexOf("/*"));
	        basePath = basePath.equals("/") ? rootPath : (new StringBuilder()).append(basePath).append(rootPath).toString();
	        config.setBasePath(basePath);
	        config.setScan(true);
	    }

	/**
     * collect all hibernate entity classes for HibernateBundle.
     * 
     */
    private List<Class<?>> initSfEntityClass()
    {
        List<Class<?>> sfEntitysList = new ArrayList<Class<?>>();
        
        sfEntitysList.addAll(FmDbMapper.getFmEntityClasses());
        
        return sfEntitysList;
    }
}
